<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>轮播图管理系统</title>
</head>
<body>

<div id="app">
    <h1 style="text-align: center">轮播图管理</h1>
    <el-button type="primary" @click="dialogVisible = true">添加图片</el-button>
    <!-- 添加图片的弹窗 -->
    <el-dialog :visible.sync="dialogVisible" title="上传图片" @close="clearDialog">
        <el-input placeholder="请输入图片描述" v-model="imageDescription" style="width: 300px; margin-bottom: 20px;"></el-input>
        <!-- 预约起始时间 -->
        <el-form :inline="true" :model="time" class="demo-form-inline">
            <el-form-item >
                <el-date-picker
                        v-model="time.endAt"
                        type="datetime"
                        placeholder="展示结束时间"
                        value-format="yyyy-MM-dd HH:mm:ss">
                </el-date-picker>
            </el-form-item>
        </el-form>

        <el-upload
                action="http://localhost:8010/Carousels/img"
                list-type="picture-card"
                :auto-upload="false"
                :file-list="fileList"
                :limit="1"
                :data="{ description: imageDescription, endAt: time.endAt }"
                :on-change="handleFileChange"
                :on-remove="handleRemove"
                :before-upload="beforeAvatarUpload"
                :on-success="handleSuccess"
                v-if="!uploaded">
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{ file }">
                <img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
                <span class="el-upload-list__item-actions">
                <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                    <i class="el-icon-zoom-in"></i>
                </span>
                <span class="el-upload-list__item-delete" @click="handleRemove(file)">
                    <i class="el-icon-delete"></i>
                </span>
            </span>
            </div>
        </el-upload>
        <div slot="footer" class="dialog-footer">
            <el-button @click="cancel">取消</el-button>
            <el-button type="primary" @click="submitUpload">上传</el-button>
        </div>
    </el-dialog>

    <!-- 更新图片的弹窗 -->
    <el-dialog :visible.sync="updateDialogVisible" title="更新图片" @close="clearUpdateDialog">
        <el-input placeholder="请输入图片描述" v-model="updateImageDescription" style="width: 300px; margin-bottom: 20px;"></el-input>
        <!-- 预约起始时间 -->
        <el-form :inline="true" :model="updateTime" class="demo-form-inline">
            <el-form-item >
                <el-date-picker
                        v-model="updateTime.endAt"
                        type="datetime"
                        placeholder="展示结束时间"
                        value-format="yyyy-MM-dd HH:mm:ss">
                </el-date-picker>
            </el-form-item>
        </el-form>

        <el-upload
                action="http://localhost:8010/Carousels/img"
                list-type="picture-card"
                :auto-upload="false"
                :file-list="updateFileList"
                :limit="1"
                :data="{ description: updateImageDescription, endAt: updateTime.endAt }"
                :on-change="handleUpdateFileChange"
                :on-remove="handleUpdateRemove"
                :before-upload="beforeUpdateAvatarUpload"
                :on-success="handleUpdateSuccess"
                v-if="!updateUploaded">
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{ file }">
                <img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
                <span class="el-upload-list__item-actions">
                <span class="el-upload-list__item-preview" @click="handleUpdatePictureCardPreview(file)">
                    <i class="el-icon-zoom-in"></i>
                </span>
                <span class="el-upload-list__item-delete" @click="handleUpdateRemove(file)">
                    <i class="el-icon-delete"></i>
                </span>
            </span>
            </div>
        </el-upload>
        <div slot="footer" class="dialog-footer">
            <el-button @click="cancelUpdate">取消</el-button>
            <el-button type="primary" @click="submitUpdate(currentUpdateId)">更新</el-button>
        </div>
    </el-dialog>

    <!-- 图片预览的弹窗 -->
    <el-dialog :visible.sync="dialogVisiblePreview">
        <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>

    <div>
        <el-table
                :data="carouselList"
                style="margin-top:20px"
                row-key="id"
                class="sortable-table">
            <el-table-column
                    prop="sortOrder"
                    label="排序序号"
                    align="center">
                <template #default="{ $index }">
                    <div style="text-align: center;">
                        {{ $index + 1 }}
                    </div>
                </template>
            </el-table-column>
            <el-table-column
                    label="预览"
                    prop="imageUrl"
                    align="center">
                <template #default="{ row }">
                    <div style="text-align: center;">
                        <img :src="row.imageUrl" width="100" height="60" @click="handlePictureCardPreview(row)">
                    </div>
                </template>
            </el-table-column>
            <el-table-column
                    label="图片描述"
                    prop="captionText"
                    align="center">
            </el-table-column>
            <el-table-column
                    label="过期时间"
                    prop="endDate"
                    align="center">
                <template #default="{ row }">
                    <div style="text-align: center;">
                        {{ formatDate(row.endDate) }}
                    </div>
                </template>
            </el-table-column>
            <el-table-column
                    label="状态"
                    align="center">
                <template #default="{ row }">
                    <div style="text-align: center;">
                        {{ isExpired(row.endDate) ? '已过期' : '未过期' }}
                    </div>
                </template>
            </el-table-column>
            <el-table-column
                    label="排序操作"
                    align="center">
                <template #default="{ $index }">
                    <div class="sort-actions" style="text-align: center">
                        <el-button
                                type="text"
                                size="mini"
                                @click="handleUpper($index)"
                                :disabled="$index === 0">
                            <i class="el-icon-arrow-up"></i>
                        </el-button>
                        <el-button
                                controls-position="center"
                                type="text"
                                size="mini"
                                @click="handleDown($index)"
                                :disabled="$index === carouselList.length - 1">
                            <i class="el-icon-arrow-down"></i>
                        </el-button>
                    </div>
                </template>
            </el-table-column>
            <el-table-column
                    label="操作"
                    align="center">
                <template #default="{ row }">
                    <div style="text-align: center">
                        <el-button
                                type="danger"
                                size="small"
                                @click="handleDelete(row.carouselId)">
                            删除
                        </el-button>
                        <el-button
                                type="success"
                                size="small"
                                @click="handleUpdate(row.carouselId)">
                            修改
                        </el-button>
                    </div>
                </template>
            </el-table-column>
        </el-table>
    </div>
</div>

<script src="js/vue.js"></script>
<script src="js/element-ui/lib/index.js"></script>
<script src="js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="js/element-ui/lib/theme-chalk/index.css">

<script>
    new Vue({
        el: '#app',
        data() {
            return {
                carouselList: [],
                dialogImageUrl: '', // 图片预览的 URL
                dialogVisible: false, // 控制添加图片弹窗的显示与隐藏
                updateDialogVisible: false, // 控制更新图片弹窗的显示与隐藏
                dialogVisiblePreview: false, // 控制图片预览弹窗的显示与隐藏
                fileList: [], // 用于存储上传的文件列表
                updateFileList: [], // 用于存储更新的文件列表
                imageDescription: '', // 用于存储图片描述
                updateImageDescription: '', // 用于存储更新的图片描述
                time: {  endAt: '' }, // 初始化时间对象
                updateTime: { endAt: '' }, // 初始化更新时间对象
                uploaded: false, // 控制上传按钮显示的变量
                updateUploaded: false, // 控制更新按钮显示的变量
                updateList: [], // 存储修改的数据
                currentUpdateId: null // 当前更新的轮播图 ID
            };
        },
        methods: {
            findAll() {
                axios.get('/Carousels')
                    .then(resp => {
                        this.carouselList = resp.data;
                    })
                    .catch(() => {
                        this.$message.error('加载数据失败！');
                    });
            },
            formatDate(dateStr) {
                if (!dateStr) return '';
                const date = new Date(dateStr);
                const year = date.getFullYear();
                const month = String(date.getMonth() + 1).padStart(2, '0');
                const day = String(date.getDate()).padStart(2, '0');
                const hours = String(date.getHours()).padStart(2, '0');
                const minutes = String(date.getMinutes()).padStart(2, '0');
                const seconds = String(date.getSeconds()).padStart(2, '0');
                return `${year}年${month}月${day}日，${hours}:${minutes}:${seconds}`;
            },
            handleUpper(index) {
                if (index === 0) return;
                this.swapItems(index, index - 1);
                this.updateSortOrder(index, index - 1);
            },
            handleDown(index) {
                if (index === this.carouselList.length - 1) return;
                this.swapItems(index, index + 1);
                this.updateSortOrder(index, index + 1);
            },
            swapItems(i, j) {
                [this.carouselList[i], this.carouselList[j]] = [this.carouselList[j], this.carouselList[i]];
            },
            updateSortOrder(fromIndex, toIndex) {
                const upId = this.carouselList[fromIndex].carouselId;
                const downId = this.carouselList[toIndex].carouselId;
                axios.post('/Carousels/updateSortOrder', {
                    upId: upId,
                    downId: downId
                })
                    .then(() => {
                        this.findAll();
                        this.$message.success('排序更新成功！');
                    })
                    .catch(error => {
                        this.$message.error(`更新失败：${error.response?.data?.msg}`);
                        this.swapItems(toIndex, fromIndex); // 回滚操作
                    });
            },
            handleDelete(id) {
                this.$confirm('确定要删除该记录？', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                })
                    .then(() => {
                        axios.delete(`/Carousels/${id}`)
                            .then(resp => {
                                this.findAll();
                                this.$message.success('删除成功!');
                            })
                            .catch(error => {
                                console.error('删除失败：', error);
                                this.$message.error("删除失败！");
                            });
                    })
                    .catch(() => {
                        this.$message.info("已取消删除");
                    });
            },
            handleUpdate(id) {
                this.currentUpdateId = id; // 设置当前更新的轮播图 ID
                const carousel = this.carouselList.find(item => item.carouselId === id);
                if (carousel) {
                    this.updateImageDescription = carousel.captionText; // 设置图片描述
                    this.updateTime.endAt = carousel.endDate; // 设置结束时间
                    this.updateFileList = [{ name: carousel.imageUrl, url: carousel.imageUrl }]; // 设置文件列表
                }
                this.updateDialogVisible = true; // 显示更新弹窗
            },
            handleFileChange(file, fileList) {
                this.fileList = fileList; // 更新文件列表
            },
            handleRemove(file, fileList) {
                this.fileList = fileList; // 更新文件列表
            },
            beforeAvatarUpload(file) {
                if (!file) {
                    this.$message.error('文件不存在，请选择一个有效的文件！');
                    return false;
                }
                if (!file.type) {
                    this.$message.error('无法识别文件类型，请选择一个有效的图片文件！');
                    return false;
                }
                const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg';
                const isLt500KB = file.size / 1024 / 1024 < 0.5; // 限制文件大小为 500KB
                if (!isJPG) {
                    this.$message.error('只能上传 JPG/PNG/JPG 格式图片!');
                    return false;
                }
                if (!isLt500KB) {
                    this.$message.error('图片大小不能超过 500KB!');
                    return false;
                }
                return true;
            },
            handlePictureCardPreview(row) {
                this.dialogImageUrl = row.imageUrl; // 设置预览图片的 URL
                this.dialogVisiblePreview = true; // 显示预览弹窗
            },
            submitUpload() {
                if (!this.imageDescription.trim()) {
                    this.$message.warning('请输入图片描述！');
                    return;
                }
                if (!this.time.endAt) {
                    this.$message.warning('请输入图片的结束展示时间！');
                    return;
                }
                if (this.fileList.length === 0) {
                    this.$message.error('请先选择要上传的图片！');
                    return;
                }
                const file = this.fileList[0].raw; // 获取当前选择的文件
                if (!this.beforeAvatarUpload(file)) {
                    return; // 如果校验失败，终止上传
                }
                const formData = new FormData();
                formData.append('file', file); // 将文件添加到 FormData 中
                formData.append('description', this.imageDescription); // 添加图片描述
                formData.append('endAt', this.time.endAt);
                axios({
                    url: '/Carousels/img', // 指定请求的URL
                    method: 'post', // 指定请求方法为POST
                    data: formData, // 传递formData作为请求体
                    headers: { 'Content-Type': 'multipart/form-data' } // 设置请求头，指定内容类型为multipart/form-data
                })
                    .then(response => {
                        this.$message.success('图片上传成功'); // 弹出成功提示
                        this.dialogVisible = false; // 关闭上传弹窗
                        this.fileList = []; // 清空文件列表
                        this.imageDescription = ''; // 清空图片描述
                        this.time.endAt = ''; // 清空结束时间
                        this.findAll(); // 刷新轮播图列表
                    })
                    .catch(error => {
                        this.$message.error('图片上传失败！'); // 弹出失败提示
                        console.error(error); // 在控制台打印错误信息
                    });
            },
            cancel() {
                this.fileList = [];
                this.imageDescription = '';
                this.time.endAt = '';
                this.dialogVisible = false;
            },
            clearDialog() {
                this.fileList = [];
                this.imageDescription = '';
                this.time.endAt = '';
            },
            handleUpdateFileChange(file, fileList) {
                this.updateFileList = fileList; // 更新文件列表
            },
            handleUpdateRemove(file, fileList) {
                this.updateFileList = fileList; // 更新文件列表
            },
            beforeUpdateAvatarUpload(file) {
                if (!file) {
                    this.$message.error('文件不存在，请选择一个有效的文件！');
                    return false;
                }
                if (!file.type) {
                    this.$message.error('无法识别文件类型，请选择一个有效的图片文件！');
                    return false;
                }
                const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg';
                const isLt500KB = file.size / 1024 / 1024 < 0.5; // 限制文件大小为 500KB
                if (!isJPG) {
                    this.$message.error('只能上传 JPG/PNG/JPG 格式图片!');
                    return false;
                }
                if (!isLt500KB) {
                    this.$message.error('图片大小不能超过 500KB!');
                    return false;
                }
                return true;
            },
            handleUpdatePictureCardPreview(file) {
                this.dialogImageUrl = file.url; // 设置预览图片的 URL
                this.dialogVisiblePreview = true; // 显示预览弹窗
            },
            isExpired(endDate) {
                const now = new Date();
                const end = new Date(endDate);
                return now > end;
            },
            submitUpdate(id) {
                if (!this.updateImageDescription.trim()) {
                    this.$message.warning('请输入图片描述！');
                    return;
                }
                if (!this.updateTime.endAt) {
                    this.$message.warning('请输入图片的结束展示时间！');
                    return;
                }

                // 检查是否有新文件被选择
                const hasNewFile = this.updateFileList.some(file => file.status === 'ready');

                let formData = new FormData();

                // 有选择新文件
                if (hasNewFile) {
                    const file = this.updateFileList[0].raw;
                    if (!file) {
                        this.$message.error('文件对象为空，请重新选择文件！');
                        return;
                    }
                    if (!this.beforeUpdateAvatarUpload(file)) {
                        return; // 如果校验失败，终止更新
                    }
                    formData.append('file', file);
                    this.updateImage(id, formData); // 调用更新方法
                } else {
                    // 获取原来的 imageUrl
                    const originalCarousel = this.carouselList.find(item => item.carouselId === id);
                    if (!originalCarousel) {
                        this.$message.error('未找到原始轮播图信息，请刷新页面或重新加载数据！');
                        return;
                    }

                    // 将 imageUrl 转换为 Blob 或 File 对象
                    fetch(originalCarousel.imageUrl)
                        .then(response => {
                            if (!response.ok) {
                                throw new Error('无法获取图片内容');
                            }
                            return response.blob(); // 将响应内容转换为 Blob
                        })
                        .then(blob => {
                            // 创建 File 对象（可选，如果你需要指定文件名等额外信息）
                            const file = new File([blob], 'originalCarouselImage.jpg', { type: blob.type });
                            formData.append('file', file);
                            this.updateImage(id, formData); // 调用更新方法
                        })
                        .catch(error => {
                            console.error('获取图片或转换文件时出错:', error);
                            this.$message.error('图片更新失败，请稍后重试！');
                        });
                }
            },

            updateImage(id, formData) {
                // 添加其他表单数据
                formData.append('description', this.updateImageDescription);
                formData.append('endAt', this.updateTime.endAt);
                formData.append('id', id);

                // 发送 formData 到后端
                axios({
                    method: 'post',
                    url: '/Carousels/updateDetail',
                    data: formData,
                    headers: { 'Content-Type': 'multipart/form-data' }
                })
                    .then(response => {
                        if (response.data > 0) {
                            this.$message.success('图片更新成功');
                            this.updateDialogVisible = false;
                            this.updateFileList = [];
                            this.updateImageDescription = '';
                            this.updateTime.endAt = '';
                            this.findAll();
                        } else {
                            this.$message.error('图片更新失败，服务器返回错误');
                        }
                    })
                    .catch(error => {
                        this.$message.error('图片更新失败！');
                        console.error("Error updating image:", error);
                    });
            },
            cancelUpdate() {
                this.updateFileList = [];
                this.updateImageDescription = '';
                this.updateTime.endAt = '';
                this.updateDialogVisible = false;
            },
            clearUpdateDialog() {
                this.updateFileList = [];
                this.updateImageDescription = '';
                this.updateTime.endAt = '';
            },
            handleSuccess(response, file, fileList) {
                if (response.success) {
                    const newImage = {
                        id: this.carouselList.length + 1,
                        imageUrl: response.data.url, // 假设服务器返回图片的 URL
                        description: this.imageDescription,
                        endDate: this.time.endAt
                    };
                    this.carouselList.push(newImage); // 将新上传的图片信息添加到carouselList数组中
                } else {
                    this.$message.error(response.message || '上传失败');
                }
            },
            handleUpdateSuccess(response, file, fileList) {
                if (response.success) {
                    this.$message.success('图片更新成功');
                    this.updateDialogVisible = false; // 关闭更新弹窗
                    this.updateFileList = []; // 清空文件列表
                    this.updateImageDescription = ''; // 清空图片描述
                    this.updateTime.endAt = ''; // 清空结束时间
                    this.findAll(); // 刷新轮播图列表
                } else {
                    this.$message.error(response.message || '更新失败');
                }
            }
        },
        mounted() {
            this.findAll(); // 初始化加载轮播图列表
        }
    });
</script>
</body>
</html>